home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
shells
/
guest-0.000
/
guest-0
/
guest-0.2
/
screen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-08
|
5KB
|
239 lines
/*
Displays menu and takes input
Copyright (C) 1995 Brian Cully
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.
please send patches (w/ explanation) or advice to: `shmit@meathook.intac.com'
*/
#include <ncurses/ncurses.h>
#include <string.h>
#include <stdio.h>
#include "screen.h"
#include "misc.h"
/* Length of NOP bar */
#define NOP_LINE_S 25
/* Output a menu item to the screen
src == menu item to display
attr == attribute */
static void display_items(struct menu_items src, int attr) {
switch (src.type) {
case MENU_TITLE:
attrset(A_NORMAL);
addch('[');
attrset(attr);
addstr(src.name);
attrset(A_NORMAL);
addch(']');
break;
case MENU_SUB:
attrset(A_NORMAL);
addch('<');
attrset(attr);
addstr(src.name);
attrset(A_NORMAL);
addstr(">");
break;
case MENU_NOP:
attrset(A_NORMAL);
if (strlen(src.name) > 1) {
addstr(src.name);
} else {
int x, y;
hline(ACS_HLINE, NOP_LINE_S);
getyx(stdscr, y, x);
move(y, NOP_LINE_S);
}
break;
case MENU_EXEC:
attrset(attr);
addstr(src.name);
break;
case MENU_EXIT:
attrset(attr);
addstr(src.name);
break;
}
addstr("\n");
}
/* Go down at least one row, skipping comments (MENU_NOP) and titles (MENU_TITLE)
*row == a pointer to the current row
**p == menu item list to sort through and display */
static void down_hilite(int *row, struct menu_items **p) {
int back_row = *row;
struct menu_items *back_item = *p;
bool quit=FALSE;
move(*row, 0);
display_items(**p, A_BOLD);
while ((*p)->next && !quit) {
*p = (*p)->next; (*row)++;
switch ((*p)->type) {
case MENU_TITLE:
case MENU_NOP:
break;
default:
quit = TRUE;
break;
}
}
if (!quit) {
*row = back_row;
*p = back_item;
}
move(*row, 0);
display_items(**p, A_REVERSE);
}
/* see down_hilite and reverse the direction */
static void up_hilite(int *row, struct menu_items **p) {
int back_row = *row;
struct menu_items *back_item = *p;
bool quit=FALSE;
move(*row, 0);
display_items(**p, A_BOLD);
while ((*p)->prev && !quit) {
*p = (*p)->prev; (*row)--;
switch ((*p)->type) {
case MENU_TITLE:
case MENU_NOP:
break;
default:
quit = TRUE;
break;
}
}
if (!quit) {
*row = back_row;
*p = back_item;
}
move(*row, 0);
display_items(**p, A_REVERSE);
}
/* display the menu list on the screen
**p == menu list to display
*row == pointer to current row */
static void init_list(struct menu_items **p, int *row) {
struct menu_items *q = *p;
attrset(A_NORMAL);
erase();
while (q->prev)
q = q->prev;
while (q) {
display_items(*q, A_BOLD);
q = q->next;
}
if (((*p)->type == MENU_TITLE) || ((*p)->type == MENU_NOP))
down_hilite(row, p);
else {
move(*row, 0);
display_items(**p, A_REVERSE);
}
refresh();
}
/* Interface to main module
Initialize the screen, must be called before anything else */
void init_scr() {
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
}
/* Interface to main module
Close the output, must be called when finished */
void close_scr() {
endwin();
}
void write_str(char *s) {
int row, col;
getyx(stdscr, row, col);
mvaddstr(row, col, s);
refresh();
}
void clear_scr() {
attrset(A_NORMAL); erase(); refresh();
}
int readchar() {
return getch();
}
/* Interface to main module
Display menu list,
*menu_list == menu list to display */
void display_list(struct menu *menu_list) {
bool quit = FALSE;
struct menu_items *p = menu_list->data;
int row=0;
if (menu_list != NULL) {
init_list(&p, &row);
while (!quit) {
switch (getch()) {
case KEY_LEFT:
quit = TRUE;
break;
case KEY_RIGHT:
switch (p->type) {
case MENU_EXIT:
quit = TRUE;
break;
default:
exec_item(*p, &menu_list);
init_list(&p, &row);
break;
}
break;
case KEY_DOWN:
down_hilite(&row, &p);
break;
case KEY_UP:
up_hilite(&row, &p);
break;
}
}
}
}